package com.danco.training.zaneuskaya.service.impl;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.danco.training.zaneuskaya.api.BookService;
import com.danco.training.zaneuskaya.api.ClaimService;
import com.danco.training.zaneuskaya.cswworker.CSVReader;
import com.danco.training.zaneuskaya.cswworker.CSVSaver;
import com.danco.training.zaneuskaya.cswworker.Separator;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.domain.Claim;

import org.apache.log4j.Logger;

import com.danco.training.zaneuskaya.service.comparator.ClaimComaratorByClaimAmount;
import com.danco.training.zaneuskaya.service.comparator.ClaimComparatorByAlphabet;
import com.danco.training.zaneuskaya.service.storage.ClaimStorage;

public class ClaimServiceImpl implements Serializable, ClaimService {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4420530563741651021L;
	private ClaimStorage claimStorage;
	private BookService bookService = BookServiceImpl
			.getBookStorageSeviceImplInstance();

	private static final Logger logger = Logger
			.getLogger(ClaimServiceImpl.class);
	private static ClaimServiceImpl claimStorageServiceInstance;

	private ClaimComparatorByAlphabet claimComparatorByAlphabet = new ClaimComparatorByAlphabet();
	private ClaimComaratorByClaimAmount claimComaratorByClaimAmount = new ClaimComaratorByClaimAmount();

	public ClaimServiceImpl() {

		this.claimStorage = ClaimStorage.getClaimStorageInstance();
	}

	public List<Claim> getList() {
		List<Claim> res = claimStorage.getClaims();
		logger.trace("Claim list");
		return res;

	}

	public List<Integer> getListId() {
		List<Integer> res = new ArrayList<Integer>();
		for (Claim c : claimStorage.getClaims()) {
			res.add(c.getId());
		}

		return res;

	}

	public int generateUnexistedId() {
		int i = 1;
		while (getListId().contains(i)) {
			i++;
		}
		return i;
	}

	public List<Claim> sortClaimsByAlphabet(List<Claim> claims) {
		Collections.sort(claims, claimComparatorByAlphabet);
		logger.trace("Claims are sorted by alphabet");
		return claims;

	}

	public List<Claim> sortClaimsByClaimAmount(List<Claim> claims) {
		Collections.sort(claims, claimComaratorByClaimAmount);
		logger.trace("Claims are sorted by the claim amoumt");
		return claims;
	}

	public Claim getById(int id) {
		for (Claim claim : claimStorage.getClaims()) {
			if (claim.getId() == id) {
				logger.trace("Claim is founded in Claimstorage by id");
				return claim;
			}
		}
		logger.info("Claim not founded in Claimstorage ");
		return null;

	}

	public boolean addEntity(Claim claim) {

		if (getById(claim.getId()) == null) {
			return claimStorage.getClaims().add(claim);

		}

		else {
			logger.info("Claim not submitted");
			return false;
		}

	}

	public boolean removeEntityById(int id) {

		if (getById(id) != null) {
			return claimStorage.getClaims().remove(getById(id));
		}
		return false;
	}

	public void saveEntityListToFile(String file) {
		ArrayList<String> res = new ArrayList<String>();
		for (Claim c : getList()) {
			res.add(entityDetails(c));
		}
		try {
			CSVSaver.saveListToFile(file, res);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
	}

	public ArrayList<Claim> readEntityList(String file) {
		ArrayList<Claim> res = new ArrayList<Claim>();
		for (int i = 0; i < CSVReader.readFile(file).length; i++) {
			String claim[] = CSVReader.readFile(file)[i]
					.split(Separator.SEPARATOR.getS());

			Claim c = new Claim(Integer.parseInt(claim[0]),
					bookService.getById(Integer.parseInt(claim[1])),
					Integer.parseInt(claim[2]));
			res.add(c);
		}
		return res;
	}

	public static ClaimServiceImpl getClaimStorageServiceInstance() {
		if (claimStorageServiceInstance == null) {
			claimStorageServiceInstance = new ClaimServiceImpl();
		}
		return claimStorageServiceInstance;
	}

	public BookService getBookService() {
		return bookService;
	}

	public void setBookService(BookService bookService) {
		this.bookService = bookService;
	}

	public String entityDetails(Claim t) {

		StringBuffer str = new StringBuffer();
		str.append(t.getId());
		str.append(Separator.SEPARATOR.getS());
		str.append(t.getBook().getId());
		str.append(Separator.SEPARATOR.getS());
		str.append(t.getClaimAmount());

		return str.toString();
	}

	@Override
	public boolean updateEntity(Claim e1, Claim e2) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean removeEntity(Claim e) {
		// TODO Auto-generated method stub
		return false;
	}

}
